<template>
  <move-dialog
    :visible="show"
    :before-close="closeDialog"
    :close-on-click-modal="false"
    width="980px"
    :title="`${type === 'add' ? '新建' : '编辑'}服务时间`"
  >
    <div class="tip">
      1、如果设置多个时间，优先级为特殊工作时间>节假日>常规工作时间<br />
      2、工作时间计算规则：常规工作时间-节假日+特殊工作时间<br />
      3、此处时间为北京时间（UTC/GMT+8）<br />
    </div>
    <el-form :model="form" ref="formRef" :rules="rules" label-position="top">
      <el-form-item label="服务时间名称" prop="name">
        <el-input
          placeholder="请输入服务时间名称"
          clearable
          maxlength="20"
          show-word-limit
          v-model.trim="form.name"
        ></el-input>
      </el-form-item>
      <el-form-item label="常规工作时间设置" prop="regularTimeConfig">
        <set-time
          type="normal"
          placeholderSelect="请选择工作日"
          :form="form"
          tip="添加工作时间"
          field="regularTimeConfig"
          :options="days.workdays"
          ref="regularTimeConfigRef"
          @onAddTime="addTime"
          @onDelTime="delTime"
          @onAddDate="addDate"
          @onDelDate="delDate"
        ></set-time>
      </el-form-item>
      <el-form-item label="特殊工作时间设置">
        <set-time
          type="special"
          placeholderSelect="请选择"
          :form="form"
          field="specialTimeConfig"
          tip="添加工作时间"
          :options="days.shiftsdays"
          ref="specialTimeConfigRef"
          @onAddTime="addTime"
          @onDelTime="delTime"
          @onAddDate="addDate"
          @onDelDate="delDate"
        ></set-time>
      </el-form-item>
      <el-form-item label="节假日设置">
        <set-time
          type="holiday"
          placeholderSelect="请选择"
          :form="form"
          tip="添加休息时间"
          field="holidayTimeConfig"
          :options="days.holidays"
          ref="holidayTimeConfigRef"
          @onAddTime="addTime"
          @onDelTime="delTime"
          @onAddDate="addDate"
          @onDelDate="delDate"
        ></set-time>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button link @click="closeDialog()">取消</el-button>
      <el-button type="primary" @click="onSave(formRef)">确定</el-button>
    </template>
  </move-dialog>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, onBeforeMount, ref, nextTick } from 'vue'
import moveDialog from '@common/components/move-dialog/index.vue'
import setTime from './set-time.vue'
import { getShiftsAndHolidays, createServiceTime, updateServiceTime } from '@app/base/apis/service-time'
import { FormInstance, ElMessage } from 'element-plus'
import { getFormatDateTime, deepClone, getCurrentDateTime } from '@/common/utils/common'
import mcCache from '@/common/utils/mc-get-cache'
interface State {
  show: boolean
  type: string
  form: any
  days: any
  rules: Record<string, unknown>
}
export default defineComponent({
  name: 'AddServiceTime',
  components: { moveDialog, setTime },
  emits: ['onRefresh'],
  setup(props, { emit }) {
    const formRef = ref<FormInstance>()
    const regularTimeConfigRef = ref<any>()
    const specialTimeConfigRef = ref<any>()
    const holidayTimeConfigRef = ref<any>()
    const STATE: State = reactive({
      days: {
        shiftsdays: [], // 调休日
        holidays: [], // 节假日
        workdays: [
          { label: '星期一', value: 'mon' },
          { label: '星期二', value: 'tue' },
          { label: '星期三', value: 'wed' },
          { label: '星期四', value: 'thu' },
          { label: '星期五', value: 'fri' },
          { label: '星期六', value: 'sat' },
          { label: '星期日', value: 'sun' }
        ] // 常规的工作日
      },
      show: false, // 弹窗是否打开
      type: '', // 控制新建还是编辑的文案
      form: {
        name: '', // 服务时间名称
        regularTimeConfig: [{ days: [], timePoint: [{}] }], // 常规时间设置
        specialTimeConfig: [{ days: [], timePoint: [{}] }], // 特殊工作日设置
        holidayTimeConfig: [{ days: [], timePoint: [{}] }] // 节假日设置
      },
      rules: {
        // 表单验证
        name: [{ required: true, message: '请输入服务时间名称', trigger: 'blur' }]
      }
    })

    //  打开弹窗
    const openDialog = (type: string, data: any) => {
      STATE.type = type
      STATE.show = true
      if (type === 'edit') {
        // 编辑
        STATE.form = handleForm(data)
      } else {
        // 新建
        resetForm()
      }
      nextTick(() => {
        regularTimeConfigRef.value.setPublicData()
        specialTimeConfigRef.value.setPublicData()
        holidayTimeConfigRef.value.setPublicData()
      })
    }

    // 关闭弹窗
    const closeDialog = () => {
      STATE.show = false
      resetForm()
    }

    // 重置表单
    const resetForm = () => {
      formRef.value?.clearValidate()
      STATE.form = {
        name: '', // 服务时间名称
        regularTimeConfig: [{ days: [], timePoint: [{}] }], // 常规时间设置
        specialTimeConfig: [], // 特殊工作日设置
        holidayTimeConfig: [] // 节假日设置
      }
    }

    // 编辑的时候，要把后台的返回的数据整理成初始化表单的形式
    const handleForm = (data: any) => {
      const handleData = deepClone(data)
      Object.keys(handleData).forEach((key: any) => {
        if (
          ['regularTimeConfig', 'specialTimeConfig', 'holidayTimeConfig'].includes(key) &&
          handleData[key].length > 0
        ) {
          handleData[key].forEach((item: any) => {
            item.timePoint.forEach((item1: any) => {
              handleTime(item1, 'period')
            })
            if (item.type === 'other' && ['specialTimeConfig', 'holidayTimeConfig'].includes(key)) {
              // 特殊工作日和节假日选择其他日期的时候，要转下选择的时间格式
              handleTime(item, 'days')
            }
          })
        }
      })
      return handleData
    }

    // 处理时间格式
    const handleTime = (item: any, type: string, isSave?: string) => {
      if (isSave) {
        const timeType = type === 'days' ? 'noTime' : 'noYear'
        if (item[type] && item[type][0] && item[type][1]) {
          item[type] = `${getFormatDateTime(item[type][0], timeType)}|${getFormatDateTime(item[type][1], timeType)}`
          if (type === 'days') {
            item[type] = [item[type]]
          }
        }
      } else if (item[type]) {
        if (typeof item[type] === 'string') {
          // 如果是字符串，转成数组
          item[type] = [item[type]]
        }
        const arr = item[type] || []
        arr.forEach((item2: string) => {
          const itemArr = item2.split('|') || []
          if (itemArr && itemArr.length > 0) {
            const dateType = type === 'days' ? '' : getCurrentDateTime().split(' ')[0] + ' '
            item[type] = [new Date(dateType + itemArr[0]), new Date(dateType + itemArr[1])]
          }
        })
      }
    }

    const hanleRepeatTime = (begin: any, end: any, arr: any, flagObj: any, key: string, str: string) => {
      // 每个时间段的时间点是否重复
      if (arr && arr[0] && arr[1]) {
        begin.push(arr[0])
        end.push(arr[1])
        begin = begin.sort()
        end = end.sort()
        for (let i = 1; i < begin.length; i++) {
          if (begin[i] <= end[i - 1]) {
            flagObj.timeMsg = `${str}的每个时间段的时间点不能重合！`
          }
        }
      } else {
        flagObj.timeMsg = `${str}的每个时间段的时间点不能为空！`
      }
      return flagObj
    }

    // 保存时间条件之前，做表单校验和数据格式整理
    const beforeSave = () => {
      const actionData = deepClone(STATE.form)
      let flagObj = { timeMsg: '', daysMsg: '' }
      Object.keys(actionData).forEach((key: any) => {
        if (
          ['regularTimeConfig', 'specialTimeConfig', 'holidayTimeConfig'].includes(key) &&
          actionData[key].length > 0
        ) {
          const str =
            key === 'regularTimeConfig'
              ? '常规工作时间设置'
              : key === 'specialTimeConfig'
              ? '特殊工作时间设置'
              : '节假日设置'
          actionData[key].forEach((item: any) => {
            const begin: any = []
            const end: any = []
            item.timePoint.forEach((item1: any) => {
              // 每个时间段的时间点是否重合
              flagObj = hanleRepeatTime(begin, end, item1.period, flagObj, key, str)
              //整理时间格式
              handleTime(item1, 'period', 'save')
            })
            if (item.days && item.days.length <= 0) {
              flagObj.daysMsg = `${str}的每个日期不能为空！`
            }
            if (item.type === 'other' && ['specialTimeConfig', 'holidayTimeConfig'].includes(key)) {
              // 特殊工作日和节假日选择其他日期的时候，要转下选择的时间格式
              handleTime(item, 'days', 'save')
            }
          })
        }
      })
      if (flagObj.daysMsg) {
        // 每个日期不能为空，也不能有重合
        ElMessage.error(flagObj.daysMsg)
        return 'no'
      } else if (flagObj.timeMsg) {
        // 每个日期的时间段不能为空，也不能有重合
        ElMessage.error(flagObj.timeMsg)
        return 'no'
      }
      return actionData
    }

    // 保存服务时间
    const onSave = (formEl: FormInstance | undefined) => {
      if (!formEl) return
      formEl.validate((valid) => {
        if (valid) {
          const actionFrom = beforeSave()
          if (actionFrom === 'no') {
            // 表单验证未通过
            return false
          }
          let actionFun = createServiceTime
          if (STATE.type === 'edit') {
            actionFun = updateServiceTime
          }
          actionFun(actionFrom).then((res: any) => {
            if (res && res.success) {
              ElMessage.success('操作成功')
              emit('onRefresh')
              closeDialog()
              if (STATE.type === 'add' && res.data) {
                // 更新缓存
                mcCache.$addOneCache('serviceTime', res.data, 'hasObj', 'id')
              } else {
                mcCache.$updateCache('serviceTime', res.data, '_id', '')
              }
            }
          })
        } else {
          return false
        }
      })
    }

    // 增加时间
    const addTime = ({ i, field }: any) => {
      STATE.form[field][i].timePoint.push({})
    }

    // 删除时间
    const delTime = ({ i, index, field }: any) => {
      STATE.form[field][i].timePoint.splice(index, 1)
    }

    // 添加日期
    const addDate = ({ i, type, field }: any) => {
      STATE.form[field].push({ days: [], timePoint: [{}], type })
    }

    // 删除日期
    const delDate = ({ i, field }: any) => {
      STATE.form[field].splice(i, 1)
    }

    // 处理节假日，数据是从http://www.apihubs.cn/#/holiday拉回来的，不同的类型，取的字段不一样
    const handleHolidays = (days: Record<string, unknown>[], type: string) => {
      const arr: any = []
      days.forEach((item: any) => {
        let newItemDate = (item.date && item.date.toString()) || ''
        newItemDate = `${newItemDate.substring(0, 4)}-${newItemDate.substring(4, 6)}-${newItemDate.substring(6, 8)}`
        arr.push({
          label: `${newItemDate}  ${type === 'holidays' ? item.holiday_cn : item.holiday_overtime_cn}`,
          value: `${newItemDate}  ${type === 'holidays' ? item.holiday_cn : item.holiday_overtime_cn}`,
          disabled: false
          // value把节假日的中文也加上，是为了第二年看去年的数据，回显还是有中文，下拉列表中已经没有去年的节假日了。
        })
      })
      return arr
    }

    // 查询节假日
    const onFetchHolday = () => {
      getShiftsAndHolidays({}).then((res) => {
        if (res && res.success && res.data) {
          STATE.days.shiftsdays = handleHolidays(res.data.shifts || [], 'shifts')
          STATE.days.holidays = handleHolidays(res.data.holidays || [], 'holidays')
        }
      })
    }

    // 首次获取节假日配置
    onBeforeMount(() => {
      onFetchHolday()
    })

    return {
      ...toRefs(STATE),
      openDialog,
      closeDialog,
      onSave,
      addTime,
      delTime,
      addDate,
      delDate,
      formRef,
      regularTimeConfigRef,
      specialTimeConfigRef,
      holidayTimeConfigRef
    }
  }
})
</script>

<style lang="stylus" scoped>
.tip {
  padding: 16px;
  background: rgba(30, 99, 245, 0.1);
  border-radius: 4px;
  line-height: 18px;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.88);
  margin-bottom: 16px;
}
</style>
